#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(std::vector<std::vector<int>> m1, std::vector<std::vector<int>> m2, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

//    matrix = m1;
//    scale = 1000/matrix1.size();

//    aco.getMatrix(matrix1);
//    aco.setScale(scale);
//    orAco.getMatrix(matrix1);
//    orAco.setScale(scale);

    matrix1 = m1;
    matrix2 = m2;

    t1 = new QTextBrowser(this);
    t1->setText("蚁群算法");
    t1->move(1020, 100);
    t1->resize(160, 100);

    b0 = new QPushButton("改进蚁群算法", this);
    b0->move(1050, 780);
    b0->resize(100, 50);


    b1 = new QPushButton("基础蚁群算法", this);
    b1->move(1050, 850);
    b1->resize(100, 50);

    b2 = new QPushButton("清除", this);
    b2->move(1050, 920);
    b2->resize(100, 50);

    b3 = new QPushButton("地图1", this);
    b3->move(1050, 640);
    b3->resize(100, 50);

    b4 = new QPushButton("地图2", this);
    b4->move(1050, 710);
    b4->resize(100, 50);

    connect(b3, &QPushButton::clicked, this, &MainWindow::setMat1);
    connect(b4, &QPushButton::clicked, this, &MainWindow::setMat2);

    connect(b0, &QPushButton::clicked, this, &MainWindow::acoT);
    connect(b1, &QPushButton::clicked, this, &MainWindow::acoP);
    connect(b2, &QPushButton::clicked, this, &MainWindow::clear);

    connect(this, &MainWindow::sig, this, &MainWindow::sol);
    connect(this, &MainWindow::oSig, this, &MainWindow::oSol);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setMat1() {


    scale = 1000/matrix1.size();
    matrix = matrix1;

    aco.getMatrix(matrix);
    aco.setScale(scale);
    orAco.getMatrix(matrix);
    orAco.setScale(scale);

    update();
}

void MainWindow::setMat2() {
    scale = 1000/matrix2.size();
    matrix = matrix2;

    aco.getMatrix(matrix);
    aco.setScale(scale);
    orAco.getMatrix(matrix);
    orAco.setScale(scale);

    update();
}

void MainWindow::paintEvent(QPaintEvent *event) {
    QPainter p(this);

    int rows = matrix.size();
    for(int i = 1; i <= rows; ++i) {
        p.drawLine(QPoint(i*scale,0), QPoint(i*scale, scale*matrix.size()));
    }
    for(int i = 1; i < rows; ++i) {
        p.drawLine(QPoint(0, i*scale), QPoint(scale*matrix.size(), i*scale));
    }

    QBrush brush;
    brush.setColor(Qt::gray);
    brush.setStyle(Qt::SolidPattern);
    p.setBrush(brush);

    for(int i=0; i<rows; ++i) {
        for(int j=0; j< rows; ++j) {
            if(matrix[i][j])
                p.drawRect(QRect(QPoint(j*scale,i*scale), QPoint((j+1)*scale-1,(i+1)*scale-1)));
        }
    }

    QPen pen;

    pen.setColor(Qt::blue);
    pen.setWidth(3);
    p.setPen(pen);
    if(flag) {
        for (int j = 0; j < k; ++j)

            p.drawPoint(oRoute[j].x(), oRoute[j].y());
    }

    pen.setColor(Qt::red);
    pen.setWidth(3);
    p.setPen(pen);
    if(flag) {
        for (int j = 0; j < i; ++j)
            p.drawPoint(route[j].x(), route[j].y());
    }

    brush.setColor(Qt::cyan);
    brush.setStyle(Qt::SolidPattern);
    p.setBrush(brush);
    if(sFlag) {
        p.drawEllipse(QRect(QPoint(start.x()-15, start.y()-15), QSize(30,30)));
        if(eFlag) {
            p.drawEllipse(QRect(QPoint(end.x()-15, end.y()-15), QSize(30,30)));
            return;
        }
        //std::cout << std::endl;
    }
}


void MainWindow::acoT() {

    route.clear();
    i = 0;

    flag = true;
    aco.setStartStop(start, end);


    staT = clock();
    route = aco.process();
    endsT = clock();

    v1t.push_back(endsT-staT);
    std::cout << "current time:" << (endsT-staT)/CLOCKS_PER_SEC << std::endl;
    std::sort(v1t.begin(),v1t.end());
    std::cout << "minT:" << v1t[0]/CLOCKS_PER_SEC << std::endl;
    std::cout << "maxT:" << v1t[v1t.size()-1]/CLOCKS_PER_SEC << std::endl;
    float ta=0;
    for(int i=0;i<v1t.size();i++){
        ta+=v1t[i];
    }
    ta/=v1t.size();
    std::cout << "averageT:" << ta/CLOCKS_PER_SEC << std::endl;

    //std::cout << "change time:" << endsT-staT << std::endl;

    min = aco.getMin();

    v1.push_back(min);
    std::sort(v1.begin(),v1.end());
    std::cout << "min:" << v1[0] << std::endl;
    std::cout << "max:" << v1[v1.size()-1] << std::endl;
    float s=0;
    for(int i=0;i<v1.size();i++){
        s+=v1[i];
    }
    s/=v1.size();

    std::cout << "average:" << s << std::endl;

    sig();
    min = INT32_MAX;
    int n = route.size();
    while (i < n) {
        update();
        i++;
        Sleep(1);
        //qDebug() << i;
    }

//    eFlag = false;
//    sFlag = false;
//    flag = false;
    //i = 0;
}

void MainWindow::acoP() {

    oRoute.clear();
    k = 0;

    flag = true;
    orAco.setStartStop(start, end);

    staT = clock();
    oRoute = orAco.process();
    endsT = clock();

    v1t.push_back(endsT-staT);
    std::sort(v1t.begin(),v1t.end());
    std::cout << "minT:" << v1t[0]/CLOCKS_PER_SEC << std::endl;
    std::cout << "maxT:" << v1t[v1t.size()-1]/CLOCKS_PER_SEC << std::endl;

    float ta=0;
    for(int i=0;i<v1t.size();i++){
        ta+=v1t[i];
    }
    ta/=v1t.size();
    std::cout << "averageT:" << ta/CLOCKS_PER_SEC << std::endl;


    //std::cout << "time:" << endsT-staT << std::endl;

    oMin = orAco.getMin();

    v1.push_back(oMin);

    std::sort(v1.begin(),v1.end());
    std::cout << "min:" << v1[0] << std::endl;
    std::cout << "max:" << v1[v1.size()-1] << std::endl;

    float s=0;
    for(int i=0;i<v1.size();i++){
        s+=v1[i];
    }
    s/=v1.size();

    std::cout << "average:" << s << std::endl;

    oSig();
    oMin = INT32_MAX;
    int n = oRoute.size();
    std::cout << n << std::endl;
    while (k < n) {
        update();
        k++;
        Sleep(1);
        //qDebug() << i;
    }

//    eFlag = false;
//    sFlag = false;
//    flag = false;
    //std::cout << "xxx" << std::endl;
    //k = 0;

}

void MainWindow::mouseReleaseEvent(QMouseEvent *event) {

    if(event->x() >= 1000) {
        return;
    }

    //QMainWindow::mouseReleaseEvent(event);
    if(count == 0) {
        start.setX((event->x()/scale)*scale+scale/2);
        start.setY((event->y()/scale)*scale+scale/2);
        sFlag = true;
        qDebug() << "mouseReleaseEventstart:" << event->x() << "," << event->y();
        ++count;
    } else if (count == 1) {
        end.setX((event->x()/scale)*scale+scale/2);
        end.setY((event->y()/scale)*scale+scale/2);
        eFlag = true;
        qDebug() << "mouseReleaseEventend:" <<event->x() << "," << event->y();
        count = 0;
    }

    update();
    return;
}
